package com.yst.sqlbuilder;

import com.yst.lambda.LambdaFuncUtils;
import com.yst.lambda.TableFieldFunc;
import lombok.Data;
import lombok.experimental.Accessors;
import org.apache.commons.lang3.StringUtils;

import java.util.Objects;

@Data
@Accessors(chain = true)
public class SQLField<T> implements IFieldExpression,IAliasExpression,ISQLExpression {

    public static <T> SQLField<T> of(TableFieldFunc<T,?> field){
        return new SQLField<T>(field);
    }

    public static <T> SQLField<T> of(TableFieldFunc<T,?> field,IAliasExpression tableAlias){
        return new SQLField<T>(field,tableAlias);
    }

    private TableFieldFunc<T,?> field;
    private IAliasExpression tableAlias;
    public SQLField<T> setTableAlias(IAliasExpression alias){
        this.tableAlias =alias;
        return this;
    }
    protected IAliasExpression getTableAlias(){
        return tableAlias;
    }

    public SQLField(TableFieldFunc<T,?> field){
        this.field=field;
    }

    public SQLField(IAliasExpression tableAlias, TableFieldFunc<T,?> field){
        this.tableAlias=tableAlias;
        this.field=field;
    }

    public SQLField(TableFieldFunc<T,?> field, IAliasExpression tableAlias){
        this.tableAlias=tableAlias;
        this.field=field;
    }

    public SQLField<T> setField(TableFieldFunc<T,?> field){
        this.field=field;
        return this;
    }

    @Override
    public String generateExpression(GenerateParam param) {
        if (StringUtils.isNotEmpty(alias)) return getRealField().concat(" AS ").concat(alias);
        return getRealField();
    }

    @Override
    public TableFieldFunc<T,?> getField() {
        return field;
    }

    @Override
    public String getRealField() {
        if (Objects.nonNull(getTableAlias())&&StringUtils.isNotEmpty(getTableAlias().getAlias())) {
            return getTableAlias().getAlias().concat(".").concat(IFieldExpression.super.getRealField());
        }
        Class<?> tableClass=LambdaFuncUtils.getOwnerClass(field);
        String realTableName= getEntitiesConfig().getTableName(tableClass);
        return realTableName.concat(".").concat(IFieldExpression.super.getRealField());
    }

    private String alias;
    public SQLField<T> setAlias(String alias){
        this.alias=alias;
        return this;
    }
    public SQLField<T> as(String alias){
        this.alias=alias;
        return this;
    }
    @Override
    public String getAlias() {
        return alias;
    }
}
